import React, {useCallback, useEffect, useMemo, useState} from 'react'
import {Button, Card, Descriptions, message, Space, Switch, Table, Tag} from 'antd'
import {HddOutlined, ReloadOutlined, SyncOutlined} from '@ant-design/icons'
import type {Database, DataSourceTreeNode, Table as TableInfo} from '@/types/source'
import {sourceApi} from '@services/api/source'

interface Props {
  selectedNode?: DataSourceTreeNode | null
  onUpdated?: () => void
}

// 专用于处理 nodeType 为 DATABASE 的右侧页面视图
export default function DatabaseDetailView({ selectedNode, onUpdated }: Props) {
  const tRaw = String((selectedNode?.nodeType ?? (selectedNode as any)?.type ?? ''))
  const t = tRaw.toUpperCase()
  const databaseName = (selectedNode as any)?.databaseName || selectedNode?.name
  const catalogName = (selectedNode as any)?.catalogName as string | undefined

  // 去除早退，确保 Hooks 始终按固定顺序调用

  const [dbInfo, setDbInfo] = useState<Database | null>(null)
  const [tables, setTables] = useState<TableInfo[]>([])
  const [loadingInfo, setLoadingInfo] = useState(false)
  const [loadingTables, setLoadingTables] = useState(false)
  const [toggling, setToggling] = useState(false)
  const [syncing, setSyncing] = useState(false)
  const [tableToggling, setTableToggling] = useState<Record<string, boolean>>({})

  const loadInfo = useCallback(async () => {
    if (!catalogName || !databaseName) return
    setLoadingInfo(true)
    const localCatalogName = catalogName
    const localDatabaseName = databaseName
    try {
      const data = await sourceApi.getDatabase(localCatalogName, localDatabaseName)
      if (catalogName !== localCatalogName || databaseName !== localDatabaseName) return
      setDbInfo(data || null)
    } catch (e) {
      console.error(e)
      message.error('加载数据库信息失败')
    } finally {
      setLoadingInfo(false)
    }
  }, [catalogName, databaseName])

  const loadTables = useCallback(async () => {
    if (!catalogName || !databaseName) return
    setLoadingTables(true)
    const localCatalogName = catalogName
    const localDatabaseName = databaseName
    try {
      const list = await sourceApi.getTables(localCatalogName, localDatabaseName)
      if (catalogName !== localCatalogName || databaseName !== localDatabaseName) return
      setTables(list || [])
    } catch (e) {
      console.error(e)
      message.error('加载表列表失败')
    } finally {
      setLoadingTables(false)
    }
  }, [catalogName, databaseName])

  useEffect(() => {
    if (!catalogName || !databaseName) return
    loadInfo()
    loadTables()
  }, [catalogName, databaseName, loadInfo, loadTables])

  const refreshAll = useCallback(async () => {
    await Promise.all([loadInfo(), loadTables()])
    onUpdated?.()
  }, [loadInfo, loadTables, onUpdated])

  const toggleEnabled = useCallback(async (enabled: boolean) => {
    setToggling(true)
    try {
      await sourceApi.setDatabaseEnabled(catalogName, databaseName, enabled)
      message.success(enabled ? '数据库已启用' : '数据库已禁用')
      await loadInfo()
      onUpdated?.()
    } catch (e) {
      console.error(e)
      message.error('更新启用状态失败')
    } finally {
      setToggling(false)
    }
  }, [catalogName, databaseName, loadInfo, onUpdated])

  const handleSync = useCallback(async () => {
    setSyncing(true)
    try {
      await sourceApi.syncDatabase(catalogName, databaseName)
      message.success('数据库同步已完成')
      await refreshAll()
    } catch (e) {
      console.error(e)
      message.error('数据库同步失败')
    } finally {
      setSyncing(false)
    }
  }, [catalogName, databaseName, refreshAll])

  // 表启用开关（若后端提供 setTableEnabled）
  const toggleTableEnabled = useCallback(async (record: any, checked: boolean) => {
    const tableName = record?.name ?? record?.tableName
    if (!tableName) {
      message.error('无法识别表名称')
      return
    }
    setTableToggling((m) => ({ ...m, [tableName]: true }))
    try {
      await sourceApi.setTableEnabled(catalogName!, databaseName!, tableName, checked)
      message.success(checked ? '表已启用' : '表已禁用')
      setTables((prev: any[]) => prev.map((t) => {
        const name = (t as any)?.name ?? (t as any)?.tableName
        if (name === tableName) return { ...t, enabled: checked }
        return t
      }))
    } catch (e) {
      console.error(e)
      message.error('更新表启用状态失败')
    } finally {
      setTableToggling((m) => ({ ...m, [tableName]: false }))
    }
  }, [catalogName, databaseName])

  // 参考数据库列表，动态生成“表列表”的完整列定义
  const buildTableColumns = useCallback((list: any[]) => {
    const keys = Array.from(new Set(list.flatMap((it) => Object.keys(it || {}))))
    const columns: any[] = []

    // 名称优先（兼容 tableName 字段）
    if (keys.includes('name') || keys.includes('tableName')) {
      columns.push({
        title: '表',
        dataIndex: 'name',
        render: (_: any, record: any) => record?.name ?? record?.tableName ?? '-',
        fixed: 'left' as const,
      })
    }

    // 已知字段的友好展示
    const known: string[] = []
    if (keys.includes('enabled')) {
      known.push('enabled')
      columns.push({
        title: '启用',
        dataIndex: 'enabled',
        render: (v: boolean, record: any) => {
          const name = record?.name ?? record?.tableName
          const loading = name ? tableToggling[name] : false
          return (
            <Switch
              checked={!!v}
              loading={!!loading}
              onChange={(checked) => toggleTableEnabled(record, checked)}
              size="small"
            />
          )
        },
      })
    }
    if (keys.includes('systemCode') || keys.includes('defaultSystemCode')) {
      known.push('systemCode')
      known.push('defaultSystemCode')
      columns.push({
        title: '系统编码',
        dataIndex: 'systemCode',
        render: (_: any, record: any) => (record?.systemCode ?? record?.defaultSystemCode ?? '-') as any,
      })
    }
    if (keys.includes('activeDimensionName')) {
      known.push('activeDimensionName')
      columns.push({
        title: '活跃维度',
        dataIndex: 'activeDimensionName',
        render: (v: string) => v || '-',
      })
    }

    // 其他返回字段全部展示（布尔显示为标签，对象/数组以JSON字符串）
    const rest = keys.filter((k) => !['name', 'tableName', 'base', 'catalogName', 'databaseName', ...known].includes(k))
    const titleOrderMap: Record<string, string> = {
      id: 'ID',
      tableName: '表名称',
      schemaName: '模式',
      rowCount: '行数',
      columnCount: '列',
      indexCount: '索引',
      constraintCount: '约束',
      statisticDt: '统计时间',
      type: '类型',
      comment: '备注',
    }
    const order = Object.keys(titleOrderMap)
    const prioritized = order.filter((k) => rest.includes(k))
    const others = rest.filter((k) => !order.includes(k))
    const restOrdered = [...prioritized, ...others]
    for (const k of restOrdered) {
      const titleMap: Record<string, string> = {
        id: 'ID',
        tableName: '表名称',
        schemaName: '模式',
        rowCount: '行数',
        columnCount: '列',
        indexCount: '索引',
        constraintCount: '约束',
        statisticDt: '统计时间',
        type: '类型',
        comment: '备注',
      }
      columns.push({
        title: titleMap[k] || k,
        dataIndex: k,
        render: (v: any) => {
          if (v === null || v === undefined) return '-'
          if (typeof v === 'boolean') return v ? <Tag color="green">是</Tag> : <Tag color="red">否</Tag>
          if (typeof v === 'object') return JSON.stringify(v)
          return String(v)
        },
      })
    }

    return columns
  }, [toggleTableEnabled, tableToggling])

  const tableColumns = useMemo(() => buildTableColumns(tables as any), [buildTableColumns, tables])

  // 非 DATABASE 类型时不渲染内容
  if (t !== 'DATABASE') return null

  // 缺少 catalogName 或 databaseName 时给出提示，避免空白页面
  if (!catalogName || !databaseName) {
    return (
      <Card size="small" title={<span><HddOutlined style={{ marginRight: 6 }} />数据库信息</span>}>
        无法识别所属目录或数据库名称，无法加载数据库数据。
      </Card>
    )
  }

  return (
    <Space direction="vertical" size="small" style={{ width: '100%' }}>
      <Card
        size="small"
        title={<span><HddOutlined style={{ marginRight: 6 }} />数据库：{databaseName}</span>}
        extra={
          <Space size="small">
            <Button size="small" icon={<ReloadOutlined />} onClick={refreshAll} loading={loadingInfo || loadingTables}>刷新</Button>
            <Button size="small" icon={<SyncOutlined />} onClick={handleSync} loading={syncing}>同步数据库</Button>
          </Space>
        }
      >
        <Descriptions
          size="small"
          column={2}
          styles={{ label: { width: 120 }, content: { minWidth: 160 } }}
        >
          <Descriptions.Item label="系统编码">{dbInfo?.systemCode || '-'}</Descriptions.Item>
          <Descriptions.Item label="启用">
            <Switch size="small" checked={!!dbInfo?.enabled} loading={toggling || loadingInfo} onChange={toggleEnabled} />
          </Descriptions.Item>
        </Descriptions>
      </Card>

      <Card size="small" title="表列表">
        <Table
          size="small"
          rowKey={(r) => (r as any).name ?? (r as any).tableName ?? JSON.stringify(r)}
          columns={tableColumns as any}
          dataSource={tables as any}
          loading={loadingTables}
          scroll={{ x: 'max-content', y: 600 }}
          pagination={false}
        />
      </Card>
    </Space>
  )
}